import { onMounted, onUnmounted, ref } from 'vue'

/**
 * @description 获取元素属性
 * @function useElementBounding(target, options)
 * @param target: CSS 选择器或 DOM 元素
 * @param options: 配置对象
 * @return object = { x, y, width, height, top, bottom, eft, right }
 * @example
   <script setup lang="ts">
     const { x, y, width, height, top, bottom, eft, right } = useElementBounding('#app')
   </script>

   <template>
     <div>rect: {{x}}, {{y}}, {{width}}, {{height}}, {{top}}, {{bottom}}, {{eft}}, {{right}}</div>
   </template>
 */
export const useElementBounding = (
  target: string | Element,
  options = {
    reset: true,
    windowResize: true,
    windowScroll: true,
    immediate: true
  }
) => {
  const { reset, windowResize, windowScroll, immediate } = options

  const x = ref(0)
  const y = ref(0)
  const width = ref(0)
  const height = ref(0)
  const top = ref(0)
  const bottom = ref(0)
  const left = ref(0)
  const right = ref(0)

  let el
  function getRect() {
    el = typeof target === 'string' ? document.querySelector(target) : target
    if (!el) {
      if (reset) {
        x.value = 0
        y.value = 0
        width.value = 0
        height.value = 0
        top.value = 0
        bottom.value = 0
        left.value = 0
        right.value = 0
      }
      throw new Error('请传入正确的 css 选择器或 dom 元素!')
    }
    const rect = el.getBoundingClientRect()
    x.value = rect.x
    y.value = rect.y
    width.value = rect.width
    height.value = rect.height
    top.value = rect.top
    bottom.value = rect.bottom
    left.value = rect.left
    right.value = rect.right
  }

  onMounted(() => {
    immediate && getRect()
    windowResize && window.addEventListener('resize', getRect)
    windowScroll && window.addEventListener('scroll', getRect)
  })
  onUnmounted(() => {
    windowResize && window.removeEventListener('resize', getRect)
    windowScroll && window.removeEventListener('scroll', getRect)
  })

  return {
    x,
    y,
    width,
    height,
    top,
    bottom,
    left,
    right
  }
}
